package com.xh.bussiness.course.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.xh.bussiness.course.bean.dto.PrepareLessonScoreDto;
import com.xh.bussiness.course.bean.request.PrepareLessonLogRequest;
import com.xh.bussiness.course.bean.request.PrepareLessonRequest;
import com.xh.bussiness.course.constant.PrepareLessonConstants;
import com.xh.bussiness.course.model.PrepareLesson;
import com.xh.bussiness.course.dao.PrepareLessonMapper;
import com.xh.bussiness.course.model.PrepareLessonLog;
import com.xh.bussiness.course.model.PrepareLessonScore;
import com.xh.bussiness.course.service.IPrepareLessonLogService;
import com.xh.bussiness.course.service.IPrepareLessonScoreService;
import com.xh.bussiness.course.service.IPrepareLessonService;
import com.xh.bussiness.permission.bean.request.QueryUserRequest;
import com.xh.bussiness.permission.model.User;
import com.xh.bussiness.permission.model.UserSchool;
import com.xh.bussiness.permission.service.IUserSchoolService;
import com.xh.bussiness.permission.service.IUserService;
import com.xh.bussiness.resource.bean.dto.MaterialDto;
import com.xh.bussiness.resource.constant.MaterialType;
import com.xh.bussiness.resource.model.Material;
import com.xh.bussiness.resource.model.MaterialPrepare;
import com.xh.bussiness.resource.service.IMaterialPrepareService;
import com.xh.bussiness.resource.service.IMaterialService;
import com.xh.bussiness.system.constant.SystemConfigConstant;
import com.xh.bussiness.system.model.Config;
import com.xh.bussiness.system.model.GroupUser;
import com.xh.bussiness.system.service.IConfigService;
import com.xh.bussiness.system.service.IGroupUserService;
import com.xh.core.service.impl.BaseServiceImpl;
import com.xh.core.util.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.xh.core.bean.XhPage;
import org.springframework.util.CollectionUtils;

import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author Pitt
 * @since 2020-12-15
 */
@Service
public class PrepareLessonServiceImpl extends BaseServiceImpl<PrepareLessonMapper, PrepareLesson> implements IPrepareLessonService {
    @Autowired
    private IUserService userService;
    @Autowired
    private IUserSchoolService userSchoolService;
    @Autowired
    private IGroupUserService groupUserService;
    @Autowired
    private IConfigService configService;
    @Autowired
    private IPrepareLessonLogService prepareLessonLogService;
    @Autowired
    private IPrepareLessonScoreService prepareLessonScoreService;
    @Autowired
    private IMaterialPrepareService materialPrepareService;
    @Autowired
    private IMaterialService materialService;

    @Override
    public XhPage queryPrepareLessonPage(XhPage page, PrepareLessonRequest bean) {
        if (StringUtils.isEmpty(bean.getCreatorId())) {
            //根据校区或分组查询用户，没传参数默认按当前用户所属校区分组进行查询
            QueryUserRequest userRequest = new QueryUserRequest();
            if (StringUtils.isEmpty(bean.getSchoolId())) {
                List<UserSchool> schools = userSchoolService.queryUserSchoolByUserId(UserUtils.getCurrentUserId());
                if (!CollectionUtils.isEmpty(schools)) {
                    userRequest.setSchoolIds(schools.stream().map(item -> item.getSchoolId()).collect(Collectors.toList()));
                }
            } else {
                userRequest.setSchoolId(bean.getSchoolId());
            }
            if (StringUtils.isEmpty(bean.getGroupId())) {
                if (StringUtils.isEmpty(bean.getSchoolId()) && CollectionUtils.isEmpty(userRequest.getSchoolIds())) {
                    List<GroupUser> groupUsers = groupUserService.queryGroupUserByUserId(UserUtils.getCurrentUserId());
                    if (!CollectionUtils.isEmpty(groupUsers)) {
                        userRequest.setGroupIds(groupUsers.stream().map(item -> item.getUserId()).collect(Collectors.toList()));
                    }
                }
            } else {
                userRequest.setGroupId(bean.getGroupId());
            }
            List<User> users = userService.queryUserList(userRequest);
            if (StringUtils.isEmpty(userRequest.getSchoolId()) && StringUtils.isEmpty(userRequest.getGroupId())
                    && CollectionUtils.isEmpty(userRequest.getGroupIds()) && CollectionUtils.isEmpty(userRequest.getSchoolIds()) && CollectionUtils.isEmpty(users)) {
                return page;
            }
            bean.setCreatorIds(users.stream().map(item -> item.getId()).collect(Collectors.toList()));
        }

        page = this.dao.queryPrepareLessonByPage(page, bean);
        return page;
    }

    @Override
    public List queryPrepareLesson(PrepareLessonRequest bean) {
        QueryWrapper qw = new QueryWrapper<PrepareLesson>();
        //拼装条件
        qw = prepareParams(bean, qw);

        return this.dao.selectList(qw);
    }

    @Override
    public PrepareLesson queryByUserId(String userId, String courseId, String courseIndexId) {
        QueryWrapper<PrepareLesson> qw = new QueryWrapper<>();
        qw.eq("creator_id", userId);
        qw.eq("course_id", courseId);
        qw.eq("course_index", courseIndexId);
        return this.selectFirst(qw);
    }

    @Override
    public Map<String, Long> queryMaterialCountById(String prepareLessonId) {
        List<MaterialDto> materialDtos = this.dao.queryMaterialById(prepareLessonId, null);
        Map<String, Long> resMap = new LinkedHashMap<>(16);
        long courseCount = 0;
        long handoutCount = 0;
        long mediaCount = 0;
        long otherCount = 0;
        long teachplanCount = 0;
        if (materialDtos.size() > 0) {
            Map<Integer, Long> groupbyMap = materialDtos.stream()
                    // 之前旧数据有没有type的
                    .filter(o -> o.getType() != null)
                    .collect(Collectors.groupingBy(MaterialDto::getType, Collectors.counting()));
            for (Integer key : groupbyMap.keySet()) {
                switch (key) {
                    case 1:
                        courseCount += groupbyMap.get(key);
                        break;
                    case 2:
                        handoutCount += groupbyMap.get(key);
                        break;
                    case 3:
                        mediaCount += groupbyMap.get(key);
                        break;
                    case 4:
                        otherCount += groupbyMap.get(key);
                        break;
                    case 5:
                        teachplanCount += groupbyMap.get(key);
                        break;
                    default:
                        break;
                }
            }
        }
        resMap.put(MaterialType.ALL, courseCount + handoutCount + otherCount + mediaCount + teachplanCount);
        resMap.put(MaterialType.COURSEWARE, courseCount);
        resMap.put(MaterialType.HANDOUT, handoutCount);
        resMap.put(MaterialType.TEACHPLAN, teachplanCount);
        resMap.put(MaterialType.MEDIA, mediaCount);
        resMap.put(MaterialType.OTHER, otherCount);

        return resMap;
    }

    @Override
    public List<MaterialDto> queryMaterialByPrepareLessonId(String prepareLessonId, Integer type) {
        return this.dao.queryMaterialById(prepareLessonId, type);
    }

    @Override
    public Map<String, Object> queryPrepareLessonAnalysis(String subjectCode, String schoolId, String groupId) {
        Map<String, Object> retMap = new HashMap<>();
        //备课平均分
        Double prepareLessonAvgScore = 0.0;
        //教案上传率
        Double uploadTeachPlanRate = 0.0;
        //还课视频上传率
        Double uploadReviewVideoRate = 0.0;

        retMap.put("prepareLessonAvgScore", prepareLessonAvgScore);
        retMap.put("uploadTeachPlanRate", uploadTeachPlanRate);
        retMap.put("uploadReviewVideoRate", uploadReviewVideoRate);

        //根据校区或分组查询用户，没传参数默认按当前用户所属校区分组进行查询
        QueryUserRequest userRequest = new QueryUserRequest();
        if (StringUtils.isEmpty(schoolId)) {
            List<UserSchool> schools = userSchoolService.queryUserSchoolByUserId(UserUtils.getCurrentUserId());
            if (!CollectionUtils.isEmpty(schools)) {
                userRequest.setSchoolIds(schools.stream().map(item -> item.getSchoolId()).collect(Collectors.toList()));
            }
        } else {
            userRequest.setSchoolId(schoolId);
        }
        if (StringUtils.isEmpty(groupId)) {
            if (StringUtils.isEmpty(schoolId) && CollectionUtils.isEmpty(userRequest.getSchoolIds())) {
                List<GroupUser> groupUsers = groupUserService.queryGroupUserByUserId(UserUtils.getCurrentUserId());
                if (!CollectionUtils.isEmpty(groupUsers)) {
                    userRequest.setGroupIds(groupUsers.stream().map(item -> item.getUserId()).collect(Collectors.toList()));
                }
            }
        } else {
            userRequest.setGroupId(groupId);
        }
        List<User> users = userService.queryUserList(userRequest);
        if (StringUtils.isEmpty(userRequest.getSchoolId()) && StringUtils.isEmpty(userRequest.getGroupId())
                && CollectionUtils.isEmpty(userRequest.getGroupIds()) && CollectionUtils.isEmpty(userRequest.getSchoolIds()) && CollectionUtils.isEmpty(users)) {
            return retMap;
        }

        PrepareLessonRequest condition = new PrepareLessonRequest();
        condition.setCreatorIds(users.stream().map(item -> item.getId()).collect(Collectors.toList()));
        condition.setCheckStatus(2);
        condition.setSubjectCode(subjectCode);
        //最近30天
        Calendar now = Calendar.getInstance();
        now.add(Calendar.DAY_OF_MONTH, -30);
        condition.setStartTime(DateUtils.format(now.getTime(), "yyyy/MM/dd"));
        condition.setEndTime(DateUtils.format(new Date(), "yyyy/MM/dd"));

        List<PrepareLesson> prepareLessons = this.dao.queryAllList(condition);
        if (CollectionUtils.isEmpty(prepareLessons)) {
            return retMap;
        }
        //总评分
        Double sumScore = prepareLessons.stream().mapToDouble(PrepareLesson::getScore).sum();
        //备课平均分
        prepareLessonAvgScore = MathUtils.divTwoNumberRoundHalfUp(sumScore, prepareLessons.size(), 1);
        //教案上传率
        Long uploadTeachPlanCount = prepareLessons.stream().filter(item -> item.getTeachPlan().equals(1)).count();
        uploadTeachPlanRate = MathUtils.getNumberRate(MathUtils.divTwoNumberRoundHalfUp(uploadTeachPlanCount, prepareLessons.size(), 2), 2);
        //还课视频上传率
        Long uploadReviewVideoCount = prepareLessons.stream().filter(item -> item.getReviewVideo().equals(1)).count();
        uploadReviewVideoRate = MathUtils.getNumberRate(MathUtils.divTwoNumberRoundHalfUp(uploadReviewVideoCount, prepareLessons.size(), 2), 2);

        retMap.put("prepareLessonAvgScore", prepareLessonAvgScore);
        retMap.put("uploadTeachPlanRate", uploadTeachPlanRate);
        retMap.put("uploadReviewVideoRate", uploadReviewVideoRate);

        return retMap;
    }

    @Override
    public Double queryUserPrepareLessonAvgScore(String subjectCode, String userId) {
        PrepareLessonRequest condition = new PrepareLessonRequest();
        condition.setCreatorId(userId);
        condition.setCheckStatus(2);
        condition.setSubjectCode(subjectCode);
        //最近30天
        Calendar now = Calendar.getInstance();
        now.add(Calendar.DAY_OF_MONTH, -30);
        condition.setStartTime(DateUtils.format(now.getTime(), "yyyy/MM/dd"));
        condition.setEndTime(DateUtils.format(new Date(), "yyyy/MM/dd"));

        //备课平均分 涉及排序由低到高 指定默认值为100000
        Double prepareLessonAvgScore = 100000.0;

        List<PrepareLesson> prepareLessons = this.dao.queryAllList(condition);
        if (!CollectionUtils.isEmpty(prepareLessons)) {
            //总评分
            Double sumScore = prepareLessons.stream().mapToDouble(PrepareLesson::getScore).sum();
            //备课平均分
            prepareLessonAvgScore = MathUtils.divTwoNumberRoundHalfUp(sumScore, prepareLessons.size(), 1);
        }
        return prepareLessonAvgScore;
    }

    @Override
    public PrepareLesson submitPrepare(PrepareLesson prepareLesson) {
        // 查询系统配置，如果需要审核，则该状态为审核中，如果不需要审核，怎该状态为已通过
        Integer checkStatus = PrepareLessonConstants.CheckStatus.SUBMITED,
                checkStep = 0, needGradeCheck = 0, needSchoolCheck = 0;
        Config config = configService.queryByModuleCode(SystemConfigConstant.PrepareCheck.MODULE_CODE);
        if (config != null && !org.springframework.util.StringUtils.isEmpty(config.getConfigs())) {
            JSONObject json = JSON.parseObject(config.getConfigs());
            needGradeCheck = json.getInteger(SystemConfigConstant.PrepareCheck.GRADE_CHECK) == null ? 0 : json.getInteger(SystemConfigConstant.PrepareCheck.GRADE_CHECK);
            needSchoolCheck = json.getInteger(SystemConfigConstant.PrepareCheck.SCHOOL_CHECK) == null ? 0 : json.getInteger(SystemConfigConstant.PrepareCheck.SCHOOL_CHECK);
        }
        // 需要年级审核时，审核步骤为1，否则判断校区审核，如果需要校区审核，审核步骤为2，如果都不需要，审核状态为通过
        if (needGradeCheck == 1) {
            checkStatus = PrepareLessonConstants.CheckStatus.SUBMITED;
            checkStep = 1;
        } else if (needSchoolCheck == 1) {
            checkStatus = PrepareLessonConstants.CheckStatus.SUBMITED;
            checkStep = 2;
        } else {
            checkStatus = PrepareLessonConstants.CheckStatus.PASS;
        }
        prepareLesson.setCheckStatus(checkStatus);
        prepareLesson.setCheckStep(checkStep);
        prepareLesson.setSubmitTime(new Date());
        prepareLesson.setRefuseReason("");
        prepareLesson.setRefuseType("");
        super.update(prepareLesson);
        // 新增提交记录
        PrepareLessonLogRequest bean = new PrepareLessonLogRequest();
        bean.setPrepareLessonId(prepareLesson.getId());
        List<PrepareLessonLog> list = prepareLessonLogService.queryPrepareLessonLog(bean);
        Integer optType = CollectionUtils.isEmpty(list) ? PrepareLessonConstants.OperateType.SUBMIT : PrepareLessonConstants.OperateType.RESUBMIT;
        PrepareLessonLog prepareLessonLog = new PrepareLessonLog();
        prepareLessonLog.setPrepareLessonId(prepareLesson.getId());
        prepareLessonLog.setOperatType(optType);
        prepareLessonLogService.insert(prepareLessonLog);
        return prepareLesson;
    }

    @Override
    public PrepareLessonLog checkPrepareLesson(PrepareLessonLog prepareLessonLog) {
        PrepareLessonScore prepareLessonScore = prepareLessonLog.getPrepareLessonScore();
        if (prepareLessonScore != null && prepareLessonScore.getTotalScore() > 0) {
            prepareLessonLog.setScore(prepareLessonScore.getTotalScore());
        }
        prepareLessonLogService.insert(prepareLessonLog);
        if (prepareLessonLog.getPrepareLessonScore() != null && prepareLessonLog.getPrepareLessonScore().getTotalScore() > 0) {
            prepareLessonScore.setPrepareLessonId(prepareLessonLog.getPrepareLessonId());
            prepareLessonScoreService.insert(prepareLessonScore);
        }
        Config config = configService.queryByModuleCode(SystemConfigConstant.PrepareCheck.MODULE_CODE);
        Integer checkStep = 0, needGradeCheck = 0, needSchoolCheck = 0;
        if (config != null && !org.springframework.util.StringUtils.isEmpty(config.getConfigs())) {
            JSONObject json = JSON.parseObject(config.getConfigs());
            needGradeCheck = json.getInteger(SystemConfigConstant.PrepareCheck.GRADE_CHECK) == null ? 0 : json.getInteger(SystemConfigConstant.PrepareCheck.GRADE_CHECK);
            needSchoolCheck = json.getInteger(SystemConfigConstant.PrepareCheck.SCHOOL_CHECK) == null ? 0 : json.getInteger(SystemConfigConstant.PrepareCheck.SCHOOL_CHECK);
        }
        // 需要年级审核时，审核步骤为1，否则判断校区审核，如果需要校区审核，审核步骤为2，如果都不需要，审核状态为通过
        if (needGradeCheck == 1) {
            checkStep = 1;
        } else if (needSchoolCheck == 1) {
            checkStep = 2;
        } else {
        }
        PrepareLesson prepareLesson = super.getById(prepareLessonLog.getPrepareLessonId());
        prepareLesson.setRefuseType(prepareLessonLog.getRefuseContent());
        prepareLesson.setRefuseReason(prepareLessonLog.getRefuseReason());
        prepareLesson.setCheckTime(new Date());
        prepareLesson.setReviewerId(UserUtils.getCurrentUserId());
        prepareLesson.setScore(prepareLessonLog.getScore());
        JSONObject currentUser = (JSONObject) CacheUtils.get("user_" + UserUtils.getCurrentUserId());
        if (currentUser != null) {
            String name = currentUser.getString("username");
            if (StringUtils.isEmpty(name)) {
                name = currentUser.getString("nickname");
            }
            prepareLesson.setReviewerName(name);
        }
        Integer checkStatus = prepareLessonLog.getCheckStatus();
        // 如果没通过，则直接打回，让教师重新提交
        if (PrepareLessonConstants.CheckStatus.UN_PASS == checkStatus) {
            prepareLesson.setCheckStatus(PrepareLessonConstants.CheckStatus.UN_PASS);
            prepareLesson.setCheckStep(0);
            super.update(prepareLesson);
            return prepareLessonLog;
        }
        // 如果为年级审核通过，并且不需要校区审核，则为审核通过
        if (PrepareLessonConstants.CheckStatus.PASS == checkStatus && prepareLessonLog.getOperatType() == PrepareLessonConstants.OperateType.GRADE_CHECK && needSchoolCheck == 0) {
            if (prepareLessonLog.getPrepareLessonScore() != null && prepareLessonLog.getPrepareLessonScore().getTotalScore() > 50) {
                prepareLesson.setCheckStatus(PrepareLessonConstants.CheckStatus.SCORED);
            } else {
                prepareLesson.setCheckStatus(PrepareLessonConstants.CheckStatus.PASS);
            }
            prepareLesson.setCheckStep(1);
            super.update(prepareLesson);
            return prepareLessonLog;
        }
        // 如果为年级审核通过，并且需要校区审核，则走校区审核流程，审核状态为审核中
        if (PrepareLessonConstants.CheckStatus.PASS == checkStatus && prepareLessonLog.getOperatType() == PrepareLessonConstants.OperateType.GRADE_CHECK && needSchoolCheck == 1) {
            prepareLesson.setCheckStatus(PrepareLessonConstants.CheckStatus.CHECKING);
            prepareLesson.setCheckStep(2);
            super.update(prepareLesson);
            return prepareLessonLog;
        }
        // 如果为校区审核通过，则审核通过
        if (PrepareLessonConstants.CheckStatus.PASS == checkStatus && prepareLessonLog.getOperatType() == PrepareLessonConstants.OperateType.SCHOOL_CHECK) {
            prepareLesson.setCheckStatus(PrepareLessonConstants.CheckStatus.PASS);
            prepareLesson.setCheckStep(2);
            super.update(prepareLesson);
        }
        return prepareLessonLog;
    }

    @Override
    public List<PrepareLessonLog> queryPrepareLogs(String prepareLessonId) {
        PrepareLessonLogRequest bean = new PrepareLessonLogRequest();
        bean.setPrepareLessonId(prepareLessonId);
        return prepareLessonLogService.queryPrepareLessonLog(bean);
    }

    @Override
    public PrepareLessonScoreDto queryCheckResult(String prepareLessonId) {
        QueryWrapper qw = new QueryWrapper<>();
        qw.eq("prepare_lesson_id", prepareLessonId);
        PrepareLessonScoreDto prepareLessonScore = prepareLessonScoreService.selectFirst(qw, PrepareLessonScoreDto.class);
        if (prepareLessonScore == null) {
            prepareLessonScore = new PrepareLessonScoreDto();
        }
        PrepareLesson prepareLesson = super.getById(prepareLessonId);
        prepareLessonScore.setCheckStatus(prepareLesson.getCheckStatus());
        prepareLessonScore.setRefuseReason(prepareLesson.getRefuseReason());
        prepareLessonScore.setRefuseContent(prepareLesson.getRefuseType());
        return prepareLessonScore;
    }

    @Override
    public PrepareLesson deletePrepareMaterial(String courseIndexId, String materialId) {
        materialService.delete(materialId);
        materialPrepareService.deletePrepareMaterial(courseIndexId, materialId);
        return null;
    }

    @Override
    public PrepareLesson changePrepareLessonStatus(String prepareLessonId, Integer checkStatus) {
        PrepareLesson prepareLesson = super.getById(prepareLessonId);
        prepareLesson.setCheckStatus(checkStatus);
        prepareLesson.setRefuseType("");
        prepareLesson.setRefuseReason("");
        prepareLesson.setScore(null);
        super.update(prepareLesson);
        return prepareLesson;
    }


    /**
     * 准备条件
     *
     * @param bean
     * @param qw
     */
    private QueryWrapper prepareParams(PrepareLessonRequest bean, QueryWrapper qw) {
        if (bean.getIds() != null && bean.getIds().length > 0) {
            qw.in("id", bean.getIds());
        }
        return qw;
    }
}
